#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>
#include "../../src/thread.h"

#define SIZE 100
#define PORTION 10

int TAB[SIZE];
int p_TAB[SIZE];

double getTime(){
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return 1000*tv.tv_sec+tv.tv_usec/1000.0;
}

static void* tri(void* a){
  int i,j;
  int z = *(int*)a;
 
  for(i = z; i < z + PORTION ; i++){
    for(j = i + 1; j< z+PORTION; j++){
      if(TAB[i] > TAB[j]){
	int a = TAB[j];
	TAB[j] = TAB[i];
	TAB[i] = a;
      }
    }
    thread_yield();
  } 
  printf(" TRI de T[%d...%d] = [ ",z, z+PORTION-1);
  for(i = z; i < z + PORTION ; i++)
    printf("%d ",TAB[i]);
  printf(" ]\n");
  thread_exit(NULL);
}

static void* p_tri(void* a){
  int i,j;
  int z = *(int*)a;
 
  for(i = z; i < z + PORTION ; i++){
    for(j = i + 1; j< z+PORTION; j++){
      if(p_TAB[i] > p_TAB[j]){
	int a = p_TAB[j];
	p_TAB[j] = p_TAB[i];
	p_TAB[i] = a;
      }
    }
    sched_yield();
  } 
  printf(" TRI de p_T[%d...%d] = [ ",z, z+PORTION-1);
  for(i = z; i < z + PORTION ; i++)
    printf("%d ",p_TAB[i]);
  printf(" ]\n");
  pthread_exit(NULL);
} 

int main(){
  int i;
  thread_t tid[SIZE/PORTION];
  pthread_t p_tid[SIZE/PORTION];
  int err;
  int a;
  
  for(i = 0; i<SIZE ; i++){
    TAB[i] = SIZE - i;
    p_TAB[i] = SIZE - i;
  }

  printf("     [thread]: Tableau T de taille %d]\n", SIZE); 

  double t1 = getTime();
  for(i = 0; i<SIZE/PORTION ; i++){
    a = i*PORTION;
    thread_create(tid+i,tri, (void*)&a);
  }

  for(i = 0; i<SIZE/PORTION ; i++){
    err = thread_join(tid[i], NULL);
    assert(!err);
  }
  double t2 = getTime();

  //avec pthread
  printf("\n     [pthread]: Tableau p_T de taille %d\n", SIZE); 
  int tab[SIZE/PORTION];
  double p_t1 = getTime();
  for(i = 0; i<SIZE/PORTION ; i++){
    tab[i] = i*PORTION;
    pthread_create(p_tid+i,NULL,p_tri, (void*)(tab+i));
  }

  for(i = 0; i<SIZE/PORTION ; i++){
    err = pthread_join(p_tid[i], NULL);
    assert(!err);
  }
  double p_t2 = getTime();
  
  printf("\n");
  printf("     [Cout des TRI]\n");
  printf("   avec thread = %g ms\n", t2-t1);
  printf("   avec pthread = %g ms\n", p_t2 - p_t1);
  return EXIT_SUCCESS;
}
